#include "StdAfx.h"
#include <buf\recv_buf.h>
#include <buf\send_buf.h>

using namespace fly::jld::buffer;

TEST(buf, null_recv)
{
	recv_buf req;
	EXPECT_FALSE(req.handle_header());
	EXPECT_EQ(0, req.body_size());
}
TEST(buf, less_header)
{
	recv_buf req;
	ostream os(&req.buf());
	for (size_t i = 0; i < req.header_size() - 1; ++i)
	{
		os<<"1";
	}
	EXPECT_FALSE(req.handle_header());
}
TEST(buf, more_header)
{
	recv_buf req;
	ostream os(&req.buf());
	for (size_t i = 0; i < req.header_size() + 1; ++i)
	{
		os<<"1";
	}
	EXPECT_FALSE(req.handle_header());
}

TEST(buf, proper_header)
{
	recv_buf req;
	ostream os(&req.buf());
	for (size_t i = 0; i < req.header_size(); ++i)
	{
		os<<"0";
	}
	EXPECT_FALSE(req.handle_header());
}

TEST(buf, zero_size)
{
	recv_buf req;
	ostream os(&req.buf());
	Header header;
	header.set_size(0);
	header.set_pid(MOVE);
	header.SerializeToOstream(&os);

	EXPECT_FALSE(req.handle_header());
}
TEST(buf, one_size)
{
	recv_buf req;
	ostream os(&req.buf());
	Header header;
	header.set_size(1);
	header.set_pid(MOVE);
	header.SerializeToOstream(&os);

	EXPECT_FALSE(req.handle_header());
}
TEST(buf, negative_size)
{
	recv_buf req;
	ostream os(&req.buf());
	Header header;
	header.set_size(-11);
	ASSERT_EQ(-11, header.size());
	header.set_pid(MOVE);
	header.SerializeToOstream(&os);
	EXPECT_TRUE(req.handle_header());
	EXPECT_TRUE(0 < req.body_size());
}

TEST(buf, normal)
{
	recv_buf req;
	ostream os(&req.buf());
	Header header;
	header.set_size(10);
	header.set_pid(MOVE);
	header.SerializeToOstream(&os);

	EXPECT_TRUE(req.handle_header());
	EXPECT_EQ(0, req.buf().size());
	EXPECT_EQ(10, req.body_size());
	EXPECT_EQ(MOVE, req.pid());
}

TEST(buf, parse_normal)
{
	recv_buf req;
	Move move;
	move.set_category(CHARACTER);
	ostream os(&req.buf());
	move.SerializeToOstream(&os);

	Move move2;

	ASSERT_TRUE(req.parse_from_recv(move2));

	EXPECT_EQ(move.category(), move2.category());
}

TEST(buf, parse_null)
{
	recv_buf req;
	Move move;
	ASSERT_FALSE(req.parse_from_recv(move));
}

TEST(buf, parse_fail)
{
	recv_buf req;;
	ostream os(&req.buf());
	os<<"&*^#";
	Move move;
	EXPECT_FALSE(req.parse_from_recv(move));
	EXPECT_EQ(0, move.ByteSize());
}

TEST(buf, serialize_normal)
{
	send_buf rep;
	Move move;
	move.set_category(CHARACTER);
	EXPECT_TRUE(rep.serialize_to_send(MOVE, T_SYN_TO, move));
}

TEST(buf, serialize_empty)
{
	send_buf rep;
	Move move;
	EXPECT_FALSE(rep.serialize_to_send(MOVE, T_SYN_TO, move));
	EXPECT_EQ(0, rep.buf().size());
}

TEST(buf, serialize_part)
{
	send_buf rep;
	Header header;
	header.set_size(0);
	EXPECT_EQ(5, header.ByteSize());
	EXPECT_FALSE(rep.serialize_to_send(MOVE, T_SYN_TO, header));
	EXPECT_EQ(0, rep.buf().size());
}

TEST(buf, shared)
{
	const_buf_ptr cb;
	EXPECT_FALSE(cb.unique());
}

TEST(buf, stream)
{
	asio::streambuf b;

	// reserve 512 bytes in output sequence
	asio::streambuf::mutable_buffers_type bufs = b.prepare(512);


	asio::streambuf::const_buffers_type cbf0 = b.data();
	string scb(asio::buffers_begin(cbf0), asio::buffers_end(cbf0));
	EXPECT_EQ(0, scb.size());

	ostream os(&b);
	os<<"1234";
	EXPECT_EQ(4, b.size());
	asio::streambuf::const_buffers_type cbf = b.data();

	string scb1(asio::buffers_begin(cbf), asio::buffers_end(cbf));
	EXPECT_EQ(4, scb1.size());
	EXPECT_EQ("1234", scb1);

	// received data is "committed" from output sequence to input sequence
	b.commit(5);

	EXPECT_EQ(9, b.size());
	asio::streambuf::const_buffers_type cbf2 = b.data();

	string scb2(asio::buffers_begin(cbf2), asio::buffers_end(cbf2));
	EXPECT_EQ(9, scb2.size());

	os<<"7788";
	b.commit(3);
	EXPECT_EQ(16, b.size());

	istream is(&b);
	string s;
	is >> s;

	EXPECT_EQ(0, b.size());
	EXPECT_EQ(scb2, s);
}

TEST(buf, stream_mut)
{
	asio::streambuf buf;
	size_t msize = 2<<30;
	msize += msize - 1;
	EXPECT_EQ(msize, buf.max_size());
	ostream os(&buf);
	asio::mutable_buffer mb = buf.prepare(10);
	EXPECT_EQ(msize, buf.max_size());

	os<<"1234";
	buf.commit(1);
	os<<"56789";
	buf.commit(1);
	EXPECT_EQ(11, buf.size());
}